﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.Mvc;
using System.IO;
using Telerik.Web.Mvc;
using Projectmanagement.Utl;
using ProjectManagement.Models;
using Projectmanagement.Entity;
using Telerik.Web.Mvc.UI;


namespace Projectmanagement.Controllers
{
    [RoleRequired]
    public class TaskController : Controller
    {
        public JsonResult MemberFilter(int? projectid)
        {
            if (Employee.CurrentRoleLVL >= 100)
            {
                var ms = from c in CH.DB.Members
                         where c.ProjectID == projectid && c.IsActivated
                         select new { text = c.Name, value = c.Name };
                return Json(ms, JsonRequestBehavior.AllowGet);
            }
            else
            {
                var ms = from c in CH.DB.Members
                         where c.ProjectID == projectid && c.Name == Employee.CurrentUserName
                         select new { text = c.Name, value = c.Name };
                return Json(ms, JsonRequestBehavior.AllowGet);
            }
        }

        public JsonResult MilestoneFilter(int projectid)
        {
            var ps = from s in CH.DB.Milestone.Where(s => s.Projectid == projectid)
                     select new
                     {
                         text = s.MilestoneName,
                         value = s.ID
                     };
            return Json(ps, JsonRequestBehavior.AllowGet);
        }

        public JsonResult ProjectFilter()
        {
            var ps = Helpers.GetUserProjects().Select(s =>
                new
                {
                    text = s.ProjectCode,
                    value = s.ID
                });
            return Json(ps, JsonRequestBehavior.AllowGet);
        }

        public ActionResult Operation(int? id)
        {
            var task = CH.GetDataByID<Task>(id);

            ViewBag.level = Employee.CurrentRoleLVL;
            ViewBag.listname = CH.DB.Members.Where(w => w.ProjectID == task.ProjectID).Select(x => x.Name).Distinct().ToList();
            ViewBag.files = CH.DB.TaskFiles.Where(x => x.TaskId == id).ToList();

            ViewBag.hist = (from x in CH.DB.TaskTracks
                            where x.TaskId == id
                            select x).OrderByDescending(x => x.ID);

            return View(task);
        }

        public ActionResult Index()
        {
            var selectList = from x in CH.DB.Projects select x;
            return View(selectList);
        }



        [GridAction]
        public ActionResult _SelectTaskNeedConfirmIndex(int? conferenceid, string member, string taskName)
        {

            // var task = DQ.GetSubordinateTasksSearch(conferenceid, member, true);
            var task = DQ.GetSubordinateTasksSearch(conferenceid, member, true, null, taskName);
            if (Employee.CurrentRoleLVL <= RoleLevel.Excution_Sales)
            {
                task = task.Where(w => w.Owners.Contains(Employee.CurrentUserName));
            }
            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectOverdueTaskIndex(int? conferenceid, string member, string taskName)
        {

            //var task = DQ.GetTasksSearch(conferenceid, member, 0, 0, "", true).Where(w => w.EndDate < DateTime.Now && w.TaskStateCode == _Task.InProgress);
            var task = DQ.GetTasksSearch(conferenceid, member, 0, 0, "", true, taskName).Where(w => w.EndDate < DateTime.Now && w.TaskStateCode == _Task.InProgress);
            if (Employee.CurrentRoleLVL <= RoleLevel.Excution_Sales)
            {
                task = task.Where(w => w.Owners.Contains(Employee.CurrentUserName));
            }
            if (Employee.CurrentRoleLVL == RoleLevel.Manager)
            {
                task = task.Where(w => CH.DB.Projects.Any(s => s.Manager == Employee.CurrentUserName && w.ProjectID == s.ID));
            }
            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectAllTaskIndex(int? conferenceid, string member, string taskCode)
        {
            var task = DQ.GetTasksSearch(conferenceid, member, 0, 0, "", true, taskCode);
            if (Employee.CurrentRoleLVL <= RoleLevel.Excution_Sales)
            {
                task = task.Where(w => w.Owners.Contains(Employee.CurrentUserName));
            }
            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectMyTaskIndex(int? conferenceid, string taskName)
        {
            var task = DQ.GetMyTasks(conferenceid, false, taskName);
            task = task.OrderByDescending(s => s.TaskStateID).ThenBy(s => s.EndDate);
            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectSubordinateTaskIndex(int? conferenceid, string member, string taskName)
        {
            var task = DQ.GetSubordinateTasksSearch(conferenceid, member, false, null, taskName);
            task = task.OrderByDescending(s => s.TaskStateID).ThenBy(s => s.EndDate);
            return View(new GridModel(task));
        }
        [GridAction]
        public ActionResult _SelectPassedTaskIndex(int? conferenceid, string member, string taskName)
        {
            var task = DQ.GetPassedTasks(conferenceid, member, taskName);
            if (Employee.CurrentRoleLVL <= RoleLevel.Excution_Sales)
            {
                task = task.Where(w => w.Owners.Contains(Employee.CurrentUserName));
            }
            task = task.OrderByDescending(s => s.TaskStateID).ThenBy(s => s.EndDate);
            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectNotifyTaskIndex()
        {
            var task = DQ.GetNotifyTasks();



            return View(new GridModel(task));
        }

        [GridAction]
        public ActionResult _SelectAllCustomTaskIndex(int? conferenceid, string member)
        {
            var task = DQ.GetAllCustomTasks(conferenceid, member);
            task = task.OrderByDescending(s => s.TaskStateID).ThenBy(s => s.EndDate);
            return View(new GridModel(task));
        }



        [GridAction]
        public ActionResult _SelectNotProgressTaskIndex(int? state)
        {
            var task = DQ.GetNotProgressTasks(state);
            task = task.OrderByDescending(s => s.TaskStateID).ThenBy(s => s.EndDate);
            return View(new GridModel(task));
        }



        [GridAction]
        public ActionResult _SelectWarningTaskIndex(int? conferenceid, string member, string taskName)
        {
            var members = from m in CH.DB.Members where m.ProjectID == conferenceid select m.Name;
            var warning = DateTime.Now.AddDays(-7);
            var task = DQ.GetTasksSearch(conferenceid, member, 0, 0, "", true, taskName).Where(w => members.Any(a => a == w.Owners) && w.EndDate > warning && w.TaskStateCode == _Task.InProgress);
            if (Employee.CurrentRoleLVL < RoleLevel.Excution_Sales)
            {
                task = task.Where(w => w.Owners.Contains(Employee.CurrentUserName));
            }
            return View(new GridModel(task));
        }

        private IEnumerable<_Task> getTask(int? MilestoneID)
        {
            return from c in CH.DB.Tasks
                   where c.MilestoneID == MilestoneID
                   select new _Task()
                   {
                       CreatedDate = c.CreatedDate,
                       Creator = c.Creator,
                       Description = c.Description,
                       ID = c.ID,
                       ModifiedDate = c.ModifiedDate,
                       ModifiedUser = c.ModifiedUser,
                       Sequence = c.Sequence,
                       //Complement = c.Complement,
                       EndDate = c.EndDate,
                       Name = c.Name.Length > 30 ? (c.Name.Substring(0, 30) + "......") : c.Name,
                       Owners = c.Owners,
                       ProjectID = c.ProjectID,
                       ProjectCode = c.Project.ProjectCode,
                       StartDate = c.StartDate,
                       Content = c.Content,
                       KMLinks = c.KMLinks,
                       TaskStateCode = c.TaskState != null ? c.TaskState.Code : 0,
                       Deliverables = c.Deliverables,
                       TaskStateID = c.TaskStateID,
                       FinishDate = c.FinishDate,
                       Assinger = c.Assinger,
                       TaskStateName = c.TaskState != null ? c.TaskState.Name : string.Empty,
                       TaskCode = c.TaskCode
                   };
        }


        [GridAction]
        public ActionResult _SelectIndexMilestone(int? MilestoneID)
        {
            return View(new GridModel(getTask(MilestoneID)));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult _InsertAjaxIndexMilestone(int? MilestoneID)
        {
            var item = new Task();
            if (TryUpdateModel(item))
            {
                item.MilestoneID = MilestoneID;
                TaskState ts = CH.DB.TaskStates.SingleOrDefault(x => x.Code == 30);
                if (ts != null)
                {
                    item.TaskStateID = ts.ID;
                }

                item.Assinger = Employee.CurrentUserName;
                string projectCode = CH.GetDataByID<Project>(item.ProjectID).ProjectCode;
                string prefix = projectCode;
                var records = CH.DB.Tasks.Where(s => s.TaskCode != null && s.TaskCode.StartsWith(prefix));
                if (records != null && records.Count() > 0)
                {
                    string preCode = records.OrderByDescending(s => s.ID).First().TaskCode;
                    item.TaskCode = prefix + string.Format("{0:D3}", Convert.ToInt32(preCode.Substring(preCode.Length - 3)) + 1);
                }
                else
                {
                    item.TaskCode = prefix + "001";
                }
                CH.Create<Task>(item);
            }
            return View(new GridModel(getTask(MilestoneID)));
        }

        [GridAction]
        public ActionResult _SelectIndex(int? conferenceid)
        {
            return View(new GridModel(DQ.GetTasksSearch(conferenceid, "", 0, 0, "", true)));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult _SaveAjaxEditing(int id, int? conferenceid)
        {
            string Cotents = String.IsNullOrWhiteSpace(Request["Contents"]) ? null : Request["Contents"].Trim();

            var item = CH.GetDataByID<Task>(id);
            if (TryUpdateModel(item))
            {
                if (item.ProjectID != null)
                {
                    var project = CH.DB.Projects.Find(item.ProjectID);
                    if (project != null)
                    {
                        item.Assinger = project.Manager;
                    }
                }

                CH.Edit<Task>(item);

                if (item.ID != 0 && Cotents != null)
                {
                    TaskComment comm = new TaskComment();
                    comm.CommentDate = DateTime.Now;
                    comm.Submitter = Employee.CurrentUserName;
                    comm.Contents = Cotents;
                    comm.TaskID = item.ID;
                    CH.Create<TaskComment>(comm);
                }
            }
            return View(new GridModel(DQ.GetTasksSearch(conferenceid, "", 0, 0, "", true)));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult _InsertAjaxEditingMilestone(int? conferenceid)
        {
            var item = new Task();
            //string Cotents = String.IsNullOrEmpty(Request["Contents"]) ? null : Request["Contents"].Trim();
            if (TryUpdateModel(item))
            {
                item.MilestoneID = conferenceid;
                TaskState ts = CH.DB.TaskStates.SingleOrDefault(x => x.Code == 30);
                if (ts != null)
                    item.TaskStateID = ts.ID;

                item.Assinger = Employee.CurrentUserName;
                string projectCode = CH.GetDataByID<Project>(item.ProjectID).ProjectCode;
                string prefix = projectCode;
                var records = CH.DB.Tasks.Where(s => s.TaskCode != null && s.TaskCode.StartsWith(prefix));
                if (records != null && records.Count() > 0)
                {
                    string preCode = records.OrderByDescending(s => s.ID).First().TaskCode;
                    item.TaskCode = prefix + string.Format("{0:D3}", Convert.ToInt32(preCode.Substring(preCode.Length - 3)) + 1);
                }
                else
                {
                    item.TaskCode = prefix + "001";
                }

                CH.Create<Task>(item);
                //Email.SendTaskEmail(item);
            }
            return View(new GridModel(DQ.GetTasksMilestone(conferenceid, 0, "", 0, 0, "", true)));
        }

        public JsonResult _SaveTask(Task t)
        {
            var item = CH.GetDataByID<Task>(t.ID);
            item.StartDate = t.StartDate;
            item.EndDate = t.EndDate;
            //item.Assinger = t.Assinger;
            item.Content = t.Content;
            item.Deliverables = t.Deliverables;
            item.Notify = t.Notify;
            item.FinishDate = t.FinishDate;
            item.KMLinks = t.KMLinks;
            item.Owners = t.Owners;
            item.FinishDate = t.FinishDate;
            item.MilestoneID = t.MilestoneID;
            CH.Edit<Task>(item);
            return Json("success");
        }
        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult _InsertAjaxEditing(int? conferenceid)
        {
            var item = new Task();
            //string Cotents = String.IsNullOrEmpty(Request["Contents"]) ? null : Request["Contents"].Trim();
            if (TryUpdateModel(item))
            {
                TaskState ts = CH.DB.TaskStates.SingleOrDefault(x => x.Code == 30);
                if (ts != null)
                    item.TaskStateID = ts.ID;

                item.Assinger = Employee.CurrentUserName;
                string projectCode = CH.GetDataByID<Project>(item.ProjectID).ProjectCode;
                string prefix = projectCode;
                var records = CH.DB.Tasks.Where(s => s.TaskCode != null && s.TaskCode.StartsWith(prefix));
                if (records != null && records.Count() > 0)
                {
                    string preCode = records.OrderByDescending(s => s.ID).First().TaskCode;
                    item.TaskCode = prefix + string.Format("{0:D3}", Convert.ToInt32(preCode.Substring(preCode.Length - 3)) + 1);
                }
                else
                {
                    item.TaskCode = prefix + "001";
                }

                CH.Create<Task>(item);
                //Email.SendTaskEmail(item);
            }
            return View(new GridModel(DQ.GetTasksSearch(conferenceid, "", 0, 0, "", true)));
        }

        [AcceptVerbs(HttpVerbs.Post)]
        [GridAction]
        public ActionResult _DeleteAjaxEditing(int id, int? conferenceid)
        {
            CH.Delete<Task>(id);
            return View(new GridModel(DQ.GetTasksSearch(conferenceid, "", 0, 0, "", true)));
        }

        public ActionResult GetAddComment(int? taskid)
        {
            _TaskComment comment = new _TaskComment() { TaskID = taskid, CommentDate = DateTime.Now, Submitter = Employee.CurrentUserName };

            var tcs = from tc in CH.DB.TaskComments where tc.TaskID == taskid select tc;
            ViewBag.tcs = tcs.ToList();

            return PartialView("TaskComment", comment);
        }


        [ValidateInput(false)]
        [HttpPost]
        public ActionResult AddComment(_TaskComment comment)
        {
            var added = false;
            if (ModelState.IsValid)
            {
                TaskComment comm = new TaskComment();
                comm.CommentDate = DateTime.Now;
                comm.Submitter = Employee.CurrentUserName;
                comm.Contents = comment.Contents;
                comm.TaskID = comment.TaskID;
                CH.Create<TaskComment>(comm);

                if (comm.ID != 0)
                {
                    added = true;
                }
            }
            //return RedirectToAction("Index");
            return Json(new { commentAdd = added });
        }

        public ActionResult GetCommentList(int? taskid)
        {
            var tcs = (from tc in CH.DB.TaskComments where tc.TaskID == taskid select tc)
                .OrderByDescending(x => x.ID);

            return PartialView("CommentList", tcs);
        }

        [HttpPost]
        public ActionResult SaveMsg(int taskid)
        {
            TaskComment comm = new TaskComment();
            comm.CommentDate = DateTime.Now;
            comm.Submitter = Employee.CurrentUserName;
            comm.Contents = Request.Params["msg"];
            comm.TaskID = taskid;
            CH.Create<TaskComment>(comm);

            int id = comm.ID;

            return Json("");
        }


        [HttpPost]
        public ActionResult GetDetail(int taskid)
        {
            var task = CH.DB.Tasks.Find(taskid);
            string username = Employee.CurrentUserName;
            ViewBag.level = Employee.GetRoleLevel(username);
            ViewBag.listname = CH.DB.Members.Where(w => w.ProjectID == task.ProjectID).Select(x => x.Name).Distinct().ToList();
            ViewBag.files = CH.DB.TaskFiles.Where(x => x.TaskId == taskid).ToList();

            ViewBag.hist = (from x in CH.DB.TaskTracks
                            where x.TaskId == taskid
                            select x).OrderByDescending(x => x.ID);



            return View(task);
        }





        [HttpPost]
        public ActionResult SaveStateChange(int id)
        {
            string des = Request.Params["des"];
            int state = Int32.Parse(Request.Params["state"]);
            string uname = Request.Params["uname"];
            var newstate = CH.GetAllDatas<TaskState>().FirstOrDefault(f => f.Code == state);
            Task task = CH.DB.Tasks.Find(id);
            string newstatename = newstate.Name;
            TaskTrack tt = new TaskTrack();
            tt.Content = des;
            tt.OldState = task.TaskState.Name;
            tt.NewState = newstatename;
            tt.TaskId = id;

            if (state == 30)//转发code为30，不通过也为30
            {

                if (!string.IsNullOrEmpty(uname))//转发
                {
                    tt.NewOwners = uname;
                    task.Owners = uname;
                }

                tt.TaskId = id;


                CH.Edit(task);
            }
            if (state == 100)//通过code为100
            {
                task.FinishDate = DateTime.Now;
            }
            task.TaskStateID = newstate.ID;
            CH.Create(tt);
            CH.Edit(task);
            // Email.SendTaskEmail(task);
            return Json("");
        }

        [HttpPost]
        public ActionResult UploadTaskFiles(int id)
        {
            Task t = CH.GetDataByID<Task>(id);
            StringBuilder result = new StringBuilder();
            for (int i = 0; i < Request.Files.Count; i++)
            {
                var x = Request.Files[i];
                DateTime now = DateTime.Now;
                string filename = now.Ticks.GetHashCode() + "";
                //后缀
                string suffix = x.FileName.Substring(x.FileName.LastIndexOf('.'));
                //文件夹
                string box = "/upload/" + t.Project.ProjectCode + "/taskfiles/" + id;
                //判断路径
                if (!System.IO.Directory.Exists(Server.MapPath(box)))
                {
                    System.IO.Directory.CreateDirectory(Server.MapPath(box));
                }
                //保存原图片
                var url = box + "/" + filename + suffix;
                x.SaveAs(Server.MapPath(url));

                TaskFile tf = new TaskFile();
                tf.TaskId = id;
                tf.FileName = x.FileName;
                tf.FileUrl = url;
                CH.Create(tf);
                result.AppendFormat(
                    "<li id='tf-{0}'><a href='{1}' target='_blank'>{2}</a> <a href='javascript:;' onclick='deletetaskfile({0})'>删除</a></li>"
                    , tf.ID.ToString(), tf.FileUrl, tf.FileName);
            }
            ViewBag.obj = "{validate: \"true\",msg:\"" + Server.UrlEncode(result.ToString()).Replace("+", " ") + "\"};";
            return View("_Json");
        }

        [HttpPost]
        public ActionResult DeleteFile(int id)
        {
            try
            {
                TaskFile tf = CH.DB.TaskFiles.Find(id);
                System.IO.File.Delete(Server.MapPath(tf.FileUrl));
                CH.Delete<TaskFile>(id);
                return Json("OK");
            }
            catch (Exception)
            {
                return Json("");
            }
        }

        [HttpPost]
        public ActionResult GetTaskSelectByPid(int id)
        {
            try
            {
                var tasks = CH.DB.Tasks.Where(x => x.ProjectID == id)
                    .Select(x => x.Owners).Distinct().ToList();
                string result = "<option>-请选择-</option>";
                foreach (var x in tasks)
                {
                    result += "<option value=" + x + ">" + x + "</option>";
                }
                return Json(result);
            }
            catch (Exception)
            {
                return Json("");
            }
        }

        public JsonResult GetProject()
        {



            var ss = from m in CH.DB.Projects
                     select m;
            var selectList = ss.ToList().Select(a => new SelectListItem
            {
                Text = a.ProjectCode.ToString(),
                Value = a.ID.ToString()
            });
            return Json(selectList, JsonRequestBehavior.AllowGet);

        }

        public JsonResult GetMember(int? pid)
        {
            var member = from m in CH.DB.Members
                         where m.ProjectID == pid
                         select m;
            var selectList = member.ToList().Select(a => new SelectListItem
                {
                    Text = a.Name,
                    Value = a.ID.ToString()
                });
            return Json(selectList, JsonRequestBehavior.AllowGet);
        }
    }
}
